/*
* 苏州海管家物流科技有限公司（https://www.hgj.com/）.
* 苏公网安备32059002003385号 © 2015-2022 Hgj.com All Rights Reserved. | 苏ICP备15030950号.
* @Date: 2022.05.29.
* @Author
* @Description 企点管理后台 -模块 查询条件 组件.
**/
<script setup lang="ts" name="QueryCondition">
/* setup script语法糖提供了三个新的API来供我们使用：defineProps、defineEmits。
   其中defineProps用来接收父组件传来的值props。defineEmits用来声明触发的事件表。 */

/* 在setup 语法糖中，setup可以接收两个参数，第一个参数是 props，也就是组件传值；第二个参数是context，上下文对象，
   context里面还有三个很重要的东西attrs，slots，emit。 */

// 它们分别通过defineProps、defineEmits、defineExpose 获取，无需引入


/* ref、toRef、toRefs 都可以将某个对象中的属性变成响应式数据
   ref的本质是拷贝，修改响应式数据，不会影响到原始数据，视图会更新
   toRef、toRefs的本质是引用，修改响应式数据，会影响到原始数据，视图不会更新
   toRef 一次仅能设置一个数据，接收两个参数，第一个参数是哪个对象，第二个参数是对象的哪个属性
   toRefs接收一个对象作为参数，它会遍历对象身上的所有属性，然后挨个调用toRef执行 */

/* ref可用于任何类型的数据创建响应式，取值需要加.value。对于基本数据类型，ref的性能优于reactive，而对于对象类型，ref仍然是通过reactive包装实现的。
   推荐优先使用ref，方便逻辑拆分和业务解耦。
   reactive只用于创建引用类型数据的响应式，取值不需要加.value。
   https://blog.csdn.net/ac1992122633/article/details/123763955
*/

import { toRefs } from 'vue'
import {IKey, IQuery} from "@/typings"
import {convertDateRange} from "@/utils" // 将传入的数据 id+value 组装成对象 emit出去 （id:value）

// 传入查询条件数据类型
interface ListItem {
    id: string
    options: [{
        label: string,
        value: number | string | null
    }],
    value: string | string[]
    typeName: string
    placeholder: string
    defaultValue: string
    endPlaceholder: string
    startPlaceholder: string
}
// 传入查询条件list
interface IProps {
    queryList: ListItem[],
    title?: string
    str?: string
}
// emit 方法使用的数据类型
interface IEmit {
    // eslint-disable-next-line no-unused-vars
    (e: 'emitSearch', data: IKey): void,
    // eslint-disable-next-line no-unused-vars
    (e: 'emitReset', data: IKey): void,
}
/*
  withDefaults 的第二个参数便是默认参数设置，会被编译为运行时 props 的 default 选项
  withDefaults是个函数也是无须引入开箱即用接受一个props函数第二个参数是一个对象设置默认值
*/
const props = withDefaults(defineProps<IProps>(), {
    title: '默认标题',
    str: 'defineProps 默认值',
    id: '',
    value: '',
    options: [],
    typeName: 'input',
    defaultValue: '',
    placeholder: '请输入',
    endPlaceholder: '结束日期',
    startPlaceholder: '开始日期',
    query: () => [1] // 对于array、object需要使用函数，和以前的写法一样
})

/* const props = defineProps<{
          title: string,
          queryList: ListItem[]
      }>() */
const { title, queryList } = toRefs(props)

console.log('query---------------------', title.value, queryList.value)
console.log('query---------------------', props.title, props.queryList)

// 时间控件 默认时间 选中日期后的默认具体时刻 '12:00:00', '08:00:00'
const defaultTime = [
    new Date(2022, 8, 5, 0, 0, 0),
    new Date(2022, 8, 8, 0, 0, 0)
]

const pageParam = {
    num: 0,
    size: 10
}
// const emit = defineEmits(['emitSearch', 'emitReset'])
const emit = defineEmits<IEmit>()

/**
 *@Description 查询 按钮 触发事件 .
 *@Return  将传入的数据 id+value 组装成对象 emit出去 （id:value） .
**/
const handleSearchClick = () => {
    let obj: IKey = {}
    queryList.value.forEach((item: IQuery) => {
        if (item.typeName === 'daterange' ) {
            const timeObj = convertDateRange({ ...item }) // 对时间控件 的开始，结束时间进行转换
            console.log('timeObj-------------', timeObj)
            delete obj[item.id]
            obj = { ...obj, ...timeObj }
        } else {
            obj[item.id] = item.value
        }
    })

    emit('emitSearch', {...obj, ...pageParam})
}
/**
 *@Description 重置 按钮 触发事件 .
 *@Return .
**/
const handleResetClick = () => {
    let obj: IKey = {}
    queryList.value.forEach((item: IQuery) => {
        if (item.typeName === 'daterange' ) {
            const timeObj = convertDateRange({ ...item, value: [] }) // 对时间控件 的开始，结束时间进行转换
            delete obj[item.id]
            obj = { ...obj, ...timeObj }
        } else {
            obj[item.id] = item.defaultValue
        }
    })

    emit('emitReset', {...obj, ...pageParam})
}

</script>
<template>
  <ul class="search-content">
    <template v-for="(item, index) in queryList" :key="index">
      <!-- input -->
      <li v-if="item.typeName === 'input'">
        <label class="label">{{ item.label }}</label>
        <el-input clearable :placeholder="item.placeholder" v-model.trim="item.value" />
      </li>
      <!-- select -->
      <li v-else-if="item.typeName === 'select'">
        <label class="label">{{ item.label }}</label>
        <el-select clearable :placeholder="item.placeholder" v-model="item.value">
          <el-option v-for="el in item.options" :key="el.value" :label="el.label" :value="el.value" />
        </el-select>
      </li>
      <!-- 时间范围 -->
      <li class="date-range" v-else-if="item.typeName === 'daterange'">
        <label class="label">{{ item.label }}</label>
        <el-date-picker
          clearable
          type="daterange"
          v-model="item.value"
          range-separator="至"
          :default-time="defaultTime"
          format="YYYY-MM-DD"
          value-format="YYYY-MM-DD"
          :end-placeholder="item.endPlaceholder"
          :start-placeholder="item.startPlaceholder"
        />
      </li>
    </template>

    <!-- 操作 按钮 -->
    <li class="w-auto fr">
      <el-button type="primary" @click="handleSearchClick"> 查询 </el-button>
      <el-button @click="handleResetClick"> 重置 </el-button>
    </li>
  </ul>

  <div> {{ title }} - {{ str }} </div>
</template>

<style lang="scss" scoped>
// 查询条件
.search-content {
  display: flex;
  min-width: 1000px;
  flex-wrap: wrap;
  padding: 16px 20px 0 16px;
  box-sizing: border-box;
  overflow: hidden;
  background: #fff;
  border: 1px solid orange;
  li {
    display: flex;
    // width: 260px;
    align-items: center;
    margin-bottom: 16px;
    margin-right: 20px;
    font-size: 14px;
    overflow: hidden;
    border: 1px solid blue;
  }
  .label {
    width: 85px;
    margin-right: 10px;
    text-align: right;
    color: #262d3d;
    border: 1px solid red;
  }
  // 按钮
  .w-auto {
    width: auto;
    margin-left: auto;
  }
}
// 日期 无限向下穿透 .class > :deep(input){} 只穿透一层
:deep(.el-date-editor) {
  width: 350px;
  border: 1px solid red;
}
</style>
